package com.stars.easyms.schedule.bean;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;

import com.stars.easyms.schedule.enums.TaskStatus;
import com.stars.easyms.schedule.util.DateUtil;
import lombok.Data;

/**
 * 分布式调度框架任务信息
 *
 * @author guoguifang
 */
@Data
public class DbScheduleTask implements Serializable {

    /**
     * 物理主键
     */
    private Long id;

    /**
     * 任务ID
     */
    private String taskId;

    /**
     * 任务组,若为空则表示该任务为单体任务,分组后一个任务组为一个整体按照task_step顺序执行
     */
    private String taskGroup;

    /**
     * 任务组步骤,任务组不为空时有效,同一个任务组可有相同的step表示可以同时执行
     */
    private Integer taskStep;

    /**
     * 任务名称
     */
    private String taskName;

    /**
     * 任务开关
     */
    private String taskSwitch;

    /**
     * 批次号(一个主任务从开始到结束为一个批次,用于记录日志信息,N开头表示一般批次,R开头表示失败重试批次)
     */
    private String batchNo;

    /**
     * 分区总数量，至少1个
     */
    private Integer partitionCount;

    /**
     * 分区模式：静态、动态
     */
    private String partitionMode;

    /**
     * 任务类型(本地,远程,ActiveMQ,RocketMQ)
     */
    private String taskType;

    /**
     * spring已注册的beanId
     */
    private String beanId;

    /**
     * 任务执行类的完整类名
     */
    private String beanClass;

    /**
     * 任务类型为远程时有效,远程调用的url地址
     */
    private String remoteUrl;

    /**
     * mq类型
     */
    private String mqType;

    /**
     * 任务类型为MQ时有效,与表db_schedule_mq_config关联
     */
    private String mqConfigId;

    /**
     * 任务类型为MQ时有效,如果是rocketmq则代表nameServer，如果是activemq则代表brokerUrl
     */
    private String mqConnection;

    /**
     * 任务类型为MQ时有效,连接mq的用户名
     */
    private String mqUser;

    /**
     * 任务类型为MQ时有效,连接mq的密码
     */
    private String mqPassword;

    /**
     * 任务类型为MQ并且使用rocketmq时有效,rocketmq的发送目标groupName
     */
    private String mqProducerGroupName;

    /**
     * 任务类型为MQ时有效,包含activemq和rocketmq,MQ的发送目标地址
     */
    private String mqDestination;

    /**
     * 任务类型为MQ并且使用rocketmq时有效,rocketmq的回调地址groupName
     */
    private String mqConsumerGroupName;

    /**
     * 任务类型为MQ时有效,包含activemq和rocketmq,MQ的回调通知地址
     */
    private String mqCallback;

    /**
     * 任务执行参数,使用(key1=value1,key2=value2...)的格式
     */
    private String parameters;

    /**
     * 优先级
     */
    private Integer priority;

    /**
     * 状态
     */
    private String status;

    /**
     * 状态:级别
     */
    private String statusLevel = "";

    /**
     * 周期性任务的cron表达式，支持多cron表达式用";"分割
     */
    private String cronExpression;

    /**
     * 当前数据库时间
     */
    private Timestamp currentTime;

    /**
     * 本次任务执行时间
     */
    private Timestamp currentFireTime;

    /**
     * 本次任务执行时间
     */
    private String currentFireTimeStr;

    /**
     * 本次任务完成时间
     */
    private Timestamp currentFinishTime;

    /**
     * 本次任务完成时间
     */
    private String currentFinishTimeStr;

    /**
     * 下次任务执行时间
     */
    private Timestamp nextFireTime;

    /**
     * 下次任务执行时间
     */
    private String nextFireTimeStr;

    /**
     * 错误信息
     */
    private String errorMessage;

    /**
     * 依赖的任务ID
     */
    private String dependentTaskId;

    /**
     * 依赖策略
     */
    private String dependencePolicy;

    /**
     * 任务阻塞策略(常规模式、幂等模式)
     */
    private String blockPolicy;

    /**
     * 异常策略(重试、人工、忽略)
     */
    private String errorPolicy;

    /**
     * 重试策略
     */
    private String retryPolicy;

    /**
     * 重试次数
     */
    private Integer retryCount;

    /**
     * 当前已重试次数
     */
    private Integer retryIndex;

    /**
     * 重试间隔,单位秒
     */
    private String retryInterval;

    /**
     * 是否使用白、黑名单(是:Y，否:N)
     */
    private String useWhiteBlackList;

    /**
     * 是否错误报警(是:Y，否:N)
     */
    private String alarm;

    /**
     * 乐观锁
     */
    private Long version;

    /**
     * 当前任务下拥有的所有子任务列表
     */
    private List<DbScheduleSubTask> subTaskList;

    /**
     * 创建修改主任务的数据传输对象：修改主任务需要主任务ID与乐观锁
     */
    public DbScheduleTask createUpdateTask() {
        DbScheduleTask updateTask = new DbScheduleTask();
        updateTask.setId(this.id);
        updateTask.setVersion(this.version);
        return updateTask;
    }

    public void setStatus(String status) {
        TaskStatus ts = TaskStatus.forCode(status);
        if (ts != null) {
            this.status = ts.getCode();
            this.statusLevel = ts.getLevel();
        }
    }

    public void setCurrentFireTime(Timestamp currentFireTime) {
        if (currentFireTime != null) {
            this.currentFireTime = currentFireTime;
            this.currentFireTimeStr = DateUtil.getDateStr(currentFireTime);
        }
    }

    public void setCurrentFinishTime(Timestamp currentFinishTime) {
        if (currentFinishTime != null) {
            this.currentFinishTime = currentFinishTime;
            this.currentFinishTimeStr = DateUtil.getDateStr(currentFinishTime);
        }
    }

    public void setNextFireTime(Timestamp nextFireTime) {
        if (nextFireTime != null) {
            this.nextFireTime = nextFireTime;
            this.nextFireTimeStr = DateUtil.getDateStr(nextFireTime);
        }
    }
}
